﻿namespace LogManager.Gui.AppStart
{
    using LogManager.Core.Infrastructure.Logging;
    using LogManager.Core.Models;
    using LogManager.Core.Models.Smtp;
    using LogManager.Core.Services.Location;
    using LogManager.Core.Services.Report;
    using LogManager.Gui.ViewModels;
    using LogManager.Gui.ViewModels.Processing;
    using LogManager.Gui.Views;
    using LogManager.Utils.Unity;
    using LogManager.Utils.Unity.Rules;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.InterceptionExtension;
    using System.Waf.Applications.Services;
    using System.Waf.Presentation.Services;
    using LogManager.Gui.Factories;
    using LogManager.Core.Factories;
    using LogManager.Core.Providers;

    public class AopBoot
    {
        public static void Configure(IUnityContainer container)
        {
            ConfigureForInterception(container);

            var propertyChangedBehavior = new InterceptionBehavior<PropertyChangedBehavior>();

            //register types
            container.RegisterForInterception<Configuration>(propertyChangedBehavior);
            container.RegisterForInterception<Settings>(propertyChangedBehavior);
            container.RegisterForInterception<SmtpSettings>(propertyChangedBehavior);
            container.RegisterForInterception<SmtpServer>(propertyChangedBehavior);
            container.RegisterForInterception<From>(propertyChangedBehavior);
            container.RegisterForInterception<To>(propertyChangedBehavior);
            container.RegisterForInterception<Settings>(propertyChangedBehavior);
            container.RegisterForInterception<Warehouse>(propertyChangedBehavior);
            container.RegisterForInterception<Plateform>(propertyChangedBehavior);
            container.RegisterForInterception<Server>(propertyChangedBehavior);
            container.RegisterForInterception<Location>(propertyChangedBehavior);

            // register services
            container.RegisterType<IFileDialogService, FileDialogService>();
            container.RegisterType<IMessageService, MessageService>();
            container.RegisterType<ILogger, Logger>();
            container.RegisterType<ILocationService, LocationService>();
            container.RegisterType<IReportService, ReportService>();

            // register views
            container.RegisterType<ILocationView, LocationView>();
            container.RegisterType<IServerView, ServerView>();
            container.RegisterType<IPlateformView, PlateformView>();
            container.RegisterType<IWarehouseView, WarehouseView>();
            container.RegisterType<IMainView, MainView>(new ContainerControlledLifetimeManager());
            container.RegisterType<ISettingsView, SettingsView>();
            container.RegisterType<ICheckLocationsView, CheckLocationsView>();
            container.RegisterType<IExecuteArchivingView, ExecuteArchivingView>();

            // register viewModels
            container.RegisterType<IMainViewModel, MainViewModel>(new ContainerControlledLifetimeManager(), propertyChangedBehavior);
            container.RegisterType<ISettingsViewModel, SettingsViewModel>(propertyChangedBehavior);
            container.RegisterType<ICheckLocationsViewModel, CheckLocationsViewModel>(propertyChangedBehavior);
            container.RegisterType<ILocationViewModel, LocationViewModel>(propertyChangedBehavior);
            container.RegisterType<IServerViewModel, ServerViewModel>(propertyChangedBehavior);
            container.RegisterType<IPlateformViewModel, PlateformViewModel>(propertyChangedBehavior);
            container.RegisterType<IWarehouseViewModel, WarehouseViewModel>(propertyChangedBehavior);
            container.RegisterType<IExecuteArchivingViewModel, ExecuteArchivingViewModel>(propertyChangedBehavior);

            // register miniModels  
            container.RegisterForInterception<ItemProcessModel>(propertyChangedBehavior);
            container.RegisterForInterception<SimpleStatsModel>(propertyChangedBehavior);

            // register factories
            container.RegisterType<IViewModelFactory, ViewModelFactory>();
            container.RegisterType<IXmlElementFactory, XmlElementFactory>();
            container.RegisterType<IProcessingModelFactory, ProcessingModelFactory>();
            container.RegisterType<IXmlTemplateProvider, DefaultXmlTemplateProvider>();

        }

        public static void ConfigureForInterception(IUnityContainer container)
        {
            //register we want Interception
            container.AddNewExtension<InterceptOnRegisterExtension>()
            .Configure<InterceptOnRegisterExtension>()
            .SetDefaultInterceptor<VirtualMethodInterceptor>()
            .AddNewMatchingRule<ImplementsINotifyPropertyChanged>();
        }
    }
}
